package cn.sym.system.service.impl;

import cn.sym.system.anno.PreAuthorize;
import cn.sym.system.domain.Permission;
import cn.sym.system.mapper.PermissionMapper;
import cn.sym.system.service.IPermissionScanService;
import cn.sym.system.utils.Classutil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class PermissionScanServiceImpl implements IPermissionScanService {
    private static final String  PKG_PREFIX   = "cn.sym.";
    private static final String  PKG_SUFFIX   = ".controller";

    @Autowired
    private PermissionMapper permissionMapper;
    /**
     * 自定义注解扫描，获取注解内容，保存数据到permission表
     */
    @Override
    public void annoScan() {
        //获取org.yaosang下面所有的模块目录   /D:/idea/pethome/target/classes//cn/sym/
        String path = this.getClass().getResource("/").getPath() + "cn/sym/";
        File file = new File(path);
        File[] files = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isDirectory();
            }
        });
        //获取cn.sym.*.controller里面所有的controller
        HashSet<Class> hashSet = new HashSet<>();
        for (File fileTmp : files) {
            System.out.println(fileTmp.getName());
            hashSet.addAll(Classutil.getClasses(PKG_PREFIX+fileTmp.getName()+PKG_SUFFIX));
        }
        for (Class hashset:hashSet){
            //获取到每个controller里面的方法
            Method[] methods = hashset.getMethods();
            if (methods == null){
                continue;
            }
            for (Method method:methods){
                String uri = getUri(hashset, method);
                System.out.println(uri);
                try {
                    PreAuthorize preAuthorize = method.getAnnotation(PreAuthorize.class);
                    if (preAuthorize == null){
                        continue;
                    }
                    String name = preAuthorize.name();
                    String sn = preAuthorize.value();
                    Permission permission = permissionMapper.loadBySn(sn);
                    if (permission ==null){
                        permission = new Permission();
                        permission.setName(name);
                        permission.setSn(sn);
                        permission.setUrl(uri);
                        permissionMapper.add(permission);
                    }else {
                        permission.setName(name);
                        permission.setUrl(uri);
                        permission.setSn(sn);
                        permissionMapper.update(permission);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    private String getUri(Class clazz, Method method) {
        String classPath = "";
        Annotation annotation = clazz.getAnnotation(RequestMapping.class);
        if (annotation!=null){
            RequestMapping requestMapping = (RequestMapping) annotation;
            String[] values = requestMapping.value();
            if(values!=null&&values.length>0){
                classPath = values[0];
                if (!"".equals(classPath)&&!classPath.startsWith("/"))
                    classPath="/"+classPath;
            }
        }
        GetMapping getMapping =  method.getAnnotation(GetMapping.class);
        String methodPath = "";
        if (getMapping!=null){
            String[] values = getMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        PostMapping postMapping =  method.getAnnotation(PostMapping.class);
        if (postMapping!=null){
            String[] values = postMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        DeleteMapping deleteMapping =  method.getAnnotation(DeleteMapping.class);
        if (deleteMapping!=null){
            String[] values = deleteMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        PutMapping putMapping =  method.getAnnotation(PutMapping.class);
        if (putMapping!=null){
            String[] values = putMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }

        }
        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if (patchMapping!=null){
            String[] values = patchMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if (requestMapping!=null){
            String[] values = requestMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        return classPath+methodPath;
    }

    private String getPermissionSn(String value) {
        String regex = "\\[(.*?)]";
        Pattern p = Pattern.compile("(?<=\\()[^\\)]+");
        Matcher m = p.matcher(value);
        String permissionSn =null;
        if (m.find()){
            permissionSn= m.group(0).substring(1, m.group().length()-1);
        }
        return permissionSn;
    }

    public static void main(String[] args) {
        String regex = "\\[(.*?)]";
        String text = "hasAuthority('permission:add')";
        Pattern p = Pattern.compile("(?<=\\()[^\\)]+");
        Matcher m = p.matcher(text);
        if (m.find()) {
            System.out.println(m.group(0).substring(1, m.group().length()-1));
        }
    }
}
